package ldh.im.fxbase.richtext;

import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import ldh.im.fxbase.util.FxThreadUtil;

import java.util.function.IntFunction;


public class BulletFactory implements IntFunction<Node> {
    private ImTextArea area;

    private static final Font DEFAULT_FONT = Font.font("monospace", FontPosture.ITALIC, 13);

    public BulletFactory(ImTextArea area) {
        area.getParagraphs().sizeProperty().addListener((ob, ov, nv) -> {
            if (nv <= ov) FxThreadUtil.runLater(() -> deleteParagraphCheck());
            else FxThreadUtil.runLater(() -> insertParagraphCheck());
        });
        this.area = area;
    }

    @Override
    public Node apply(int value) {
        return createGraphic(value);
    }

    private Node createGraphic(int idx) {
        Label foldIndicator = new Label("  ");
        VBox.setVgrow(foldIndicator, Priority.ALWAYS);
        foldIndicator.setMaxHeight(Double.MAX_VALUE);
        foldIndicator.setAlignment(Pos.TOP_LEFT);
        foldIndicator.setFont(DEFAULT_FONT);

        if (area.getParagraphs().size() > idx + 1) {
//            if (area.getParagraph(idx + 1).getParagraphStyle().isFolded() && !ps.isFolded()) {
//                foldIndicator.setOnMouseClicked(ME -> area.unfoldParagraphs(idx));
//                foldIndicator.getStyleClass().add("fold-indicator");
//                foldIndicator.setCursor(Cursor.HAND);
//                foldIndicator.setText("+ ");
//            }
        }

//        if (ps.isIndented() && !ps.isFolded()) {
//            foldIndicator.setGraphic(createBullet(ps.getIndent()));
//            foldIndicator.setContentDisplay(ContentDisplay.RIGHT);
//        }

        return new VBox(0, foldIndicator);
    }

    private void deleteParagraphCheck() {
        int p = area.getCurrentParagraph();
        // Was the deleted paragraph in the viewport ?
        if (p >= area.firstVisibleParToAllParIndex() && p <= area.lastVisibleParToAllParIndex()) {
            int col = area.getCaretColumn();
            // Delete was pressed on an empty paragraph, and so the cursor is now at the start of the next paragraph.
            if (col == 0) {
                // Check if the now current paragraph is folded.
//                if (area.getParagraph(p).getParagraphStyle().isFolded()) {
//                    p = Math.max(p - 1, 0);              // Adjust to previous paragraph.
//                    area.recreateParagraphGraphic(p);  // Show fold/unfold indicator on previous paragraph.
//                    area.moveTo(p, 0);                 // Move cursor to previous paragraph.
//                }
            }
            // Backspace was pressed on an empty paragraph, and so the cursor is now at the end of the previous paragraph.
            else if (col == area.getParagraph(p).length()) {
                area.recreateParagraphGraphic(p); // Shows fold/unfold indicator on current paragraph if needed.
            }
            // In all other cases the paragraph graphic is created/updated automatically.
        }
    }

    private void insertParagraphCheck() {
        int p = area.getCurrentParagraph();
        // Is the inserted paragraph in the viewport ?
        if (p > area.firstVisibleParToAllParIndex() && p <= area.lastVisibleParToAllParIndex()) {
            // Check limits, as p-1 and p+1 are accessed ...
            if (p > 0 && p + 1 < area.getParagraphs().size()) {
                // Now check if the inserted paragraph is before a folded block ?
//                if (area.getParagraph(p + 1).getParagraphStyle().isFolded()) {
//                    area.recreateParagraphGraphic(p - 1); // Remove the unfold indicator.
//                }
            }
        }
    }
}
